/**
 * 
 * @authors Your Name (you@example.org)
 * @date    2015-05-18 00:14:57
 * @version $Id$
 */
define(['angular', 'jquery', 'global/url', 'nicEditor'], function(angular, jquery, url) {
	  var services = angular.module('flightAdminApp.services', ['ngResource']);
	  services.factory('UrlService', ['$http', function($http) {
        function _doRequest(url, method, params) {
            return $http({
                url: url,
                method: method,
                data: params  
            });
        };
        return {
          doRequest : _doRequest
        }
    }]);

    /*services.factory('MissionService', ['$resource', function($resource) {
        var listQuestsURL = url.listQuestsURL();
        return $resource(listQuestsURL, {}, {
            listQuests: {method: 'GET', params: {'missionId': '@missionId', 'accessToken': '', 'filter': '@filter'}}
        });
    }]);*/

  services.factory('ActiveCodeService', ['$http', function($http) {
        
      return {
          listActiveCodes: function (data) {
              var listActiveCodesURL = url.listActiveCodesURL();
              return $http.get(listActiveCodesURL, {params: data});
          },
          updateCodeStatus: function (data) {
            var updateCodeStatusURL = url.activeCodeUpdateURL();
            return $http.post(updateCodeStatusURL, data);
          }
      }
  }]);

  services.factory('AdminsService', ['$http', function($http) {
        
      return {
          adminList: function (data) {
              var adminList = url.adminListURL();
              return $http.get(adminList, {params: data});
          }, 
          adminAdd: function (data) {
              var adminAdd = url.adminAddURL();
              return $http.post(adminAdd, data);
          },
          adminDelete: function (data) {
              var adminDelete = url.adminDeleteURL();
              return $http.post(adminDelete, data);
          }, 
         
      }
  }]);


  services.factory('MissionService', ['$http', function($http) {
        
      return {
          listQuests: function (data) {
              var listQuestsURL = url.listQuestsURL();
              return $http.get(listQuestsURL, {params: data});
          },
          listMissions: function (data) {
              var listMissionURL = url.listMissionURL();
              return $http.get(listMissionURL, {params: data});
          },
          operateMission: function (data) {
              var operateMissionURL = url.missionOperateURL();
              return $http.post(operateMissionURL, data);
          },
          operateQuest: function (data) {
              var operateQuestURL = url.questOperateURL();
              return $http.post(operateQuestURL, data);
          },
          getQuest: function (data) {
              var singleQuestURL = url.findQuestURL().replace(/\{missionId\}/, data.missionId).replace(/\{questId\}/, data.questId);
              return $http.get(singleQuestURL, {params: data});
          },
          listQuestTypes: function (data) {
              var questTypesURL = url.questTypesURL();
              return $http.get(questTypesURL, {params: data});
          }
      }
  }]);

   services.factory('ParentService', ['$http', function($http) {
      return {
         parentChildAdd: function (data) {
              var parentChildAdd = url.parentChildAddURL();
              return $http.post(parentChildAdd, data);
          },
          parentChangeEnable: function (data) {
              var  parentChangeEnable = url.parentChangeEnableURL();
              return $http.get( parentChangeEnable, {params: data});
          }, 
         parentChangeDisable: function (data) {
              var parentChangeDisable = url.parentChangeDisableURL();
              return $http.get(parentChangeDisable, {params: data});
          },
          parentChangeDebugEnable: function (data) {
              var parentChangeDebugEnable = url.parentChangeDebugEnableURL();
              return $http.get(parentChangeDebugEnable, {params: data});
          },
          parentChangeDebugDisable: function (data) {
              var parentChangeDebugDisable = url.parentChangeDebugDisableURL();
              return $http.get(parentChangeDebugDisable, {params: data});
          },
          parentList: function (data) {
              var parentList = url.parentListURL();
              return $http.get(parentList, {params: data});
          },
          parentDelete: function (data) {
              var parentDelete = url.parentDeleteURL();
              return $http.get(parentDelete, {params: data});
          },
      }
  }]);

  services.factory('ChildrenService', ['$http', function($http) {
        
      return {
          childrenItemOper: function (data) {
              var childrenItem = url.childrenItemURL();
              return $http.get(childrenItem, {params: data});
          },
          listChildren: function (data) {
              var childrenList = url.childrenListURL();
              return $http.get(childrenList, {params: data});
          },
          listChildrenView: function (data) {
              var childrenViewMission = url.childrenViewMissionURL();
              return $http.get(childrenViewMission, {params: data});
          },
          listChildrenAddItem: function (data) {
              var childrenAddItem = url.childrenAddItemURL();
              return $http.get(childrenAddItem, {params: data});
          },
          operateChildren: function (data) {
            var chilrenRejustURL = url.childrenRejustURL();
            return $http.post(chilrenRejustURL, data);
          },
          childAccountStateChange: function (data) {
            var childrenAccountStateChange = url.childrenAccountStateChangeURL();
            return $http.get(childrenAccountStateChange, {params: data});
          },
          childClearDate: function (data) {
              var childrenClearDate = url.childrenClearDateURL();
              return $http.get(childrenClearDate, {params: data});
          },
          childViewMission: function (data) {
              var childrenViewMission = url.childrenViewMissionURL();
              return $http.get(childrenViewMission, {params: data});
          },
          childMissionQuestClear: function (data) {
              var childrenMissionQuestClear = url.childrenMissionQuestClearURL();
              return $http.get(childrenMissionQuestClear, {params: data});
          },
           childMissionClear: function (data) {
              var childrenMissionClear = url.childrenMissionClearURL();
              return $http.get(childrenMissionClear, {params: data});
          },
          childdelete: function (data) {
              var childrendelete = url.childrendeleteURL();
              return $http.get(childrendelete, {params: data});
          },
          childAddItem: function (data) {
              var childrenAddItem = url.childrenAddItemURL();
              return $http.get(childrenAddItem, {params: data});
          },
         findInventory: function (data) {
              var findInventory =  url.findInventoryURL();
              return $http.get(findInventory, {params: data});
          },
          findGameSession: function (data) {
              var findGameSession =  url.findGameSessionURL();
              return $http.get(findGameSession, {params: data});
          }
      }
  }]);

  services.factory('ItemService', ['$http', function($http) {
        
      return {
          listItems: function (data) {
              var listItemsURL = url.listItemsURL();
              return $http.get(listItemsURL, {params: data});
          },
          operateItem: function (data) {
              var operateItemURL = url.itemOperateURL();
              return $http.post(operateItemURL, data);
          },
          getItemById: function (data) {
              var getItemURL = url.getItemURL().replace(/\{itemId\}/, data.itemId);
              return $http.get(getItemURL, {params: {'accessToken': data.accessToken}});
          }
      }
  }]);

   services.factory('StoreService', ['$http', function($http) {
        
      return {
          listStores: function (data) {
              var listStoreURL = url.storeListURL();
              return $http.get(listStoreURL, {params: data});
          }
      }
    }]);

    services.factory('activecodeService', ['$http', function($http) {
        
      return {
          listactivecodes: function (data) {
              var listActiveCodeURL = url.activeCodeURL();
              return $http.get(listActiveCodeURL, {params: data});
          }
      }
    }]);

   services.factory('UtilService', ['$http', '$upload', '$filter', function($http, $upload, $filter) {

      function _angularUploadFile(file, accessToken) {
          var uploadIconUrl = url.uploadItemIcon();
          return $upload.upload({
            url: uploadIconUrl,
            method: 'POST',
            file: file,
            data: {
              'accessToken': accessToken
            },
            fileFormDataName: 'itemIcon'
          });
      }

      function _renderNicEditor ($scope) {
          var editor = new nicEditor({fullPanel : true/*, uploadURI: '/flight/adminV2/upload'*/}).panelInstance('policy', {hasPanel : true});
          $scope.editor = editor;

      }

      function _getNicEditor () {
          return nicEditors.findEditor('policy');
      }

      function _validateForm (formId) {
          $(formId).validator({
              onValid: function(validity) {
                  $(validity.field).closest('.am-form-group').find('.am-alert').hide();
              },
              onInValid: function(validity) {
                  var $field = $(validity.field);
                  var $group = $field.closest('.am-form-group');
                  var $alert = $group.find('.am-alert');
                  var msg = $field.data('validationMessage') || this.getValidationMessage(validity);

                  if (!$alert.length) {
                      $alert = $('<div class="am-alert am-alert-danger"></div>').hide().
                      appendTo($group);
                  }
                  $alert.html(msg).show();
              }
          });
      }

      function _clearValidForm (formId) {
           $(formId).find('.am-form-group').removeClass('am-form-success').find('input').removeClass('am-field-valid').find('select').removeClass('am-field-valid');
      }

      function _showModal ($ele) {
          $ele.modal();
      }

      function _getChartOptions () {
          return {
                    series: {
                        lines: {
                            show: true,
                            lineWidth: 2,
                            fill: true,
                            fillColor: {
                                colors: [{
                                        opacity: 0.05
                                    }, {
                                        opacity: 0.01
                                    }
                                ]
                            }
                        },
                        points: {
                            show: true
                        },
                        shadowSize: 2
                    },
                    grid: {
                        hoverable: true,
                        clickable: true,
                        tickColor: "#eee",
                        borderWidth: 0
                    },
                    colors: ["#d12610", "#37b7f3", "#52e136"],
                    xaxis: {
                        mode: "time",  
                        timeformat: "%m/%d", 
                        minTickSize: [1, "day"]
                    },
                    yaxis: {
                        ticks: 1,
                        tickSize: 1,
                        tickDecimals: 0
                    }
                };
      }

      function _renderChart ($ele, $loading, $content, label, data) {

          if ($ele) {
              $loading.hide();
              $content.show();
              var plot_statistics = $.plot($ele, [{
                  data: data,
                  label: label
              }], _getChartOptions());
              var previousPoint = null;
              $ele.bind("plothover", function (event, pos, item) {
                  $("#x").text(pos.x.toFixed(2));
                  $("#y").text(pos.y.toFixed(2));
                  if (item) {
                      if (previousPoint != item.dataIndex) {
                          previousPoint = item.dataIndex;
                          $("#tooltip").remove();
                          var x = item.datapoint[0].toFixed(2);
                          var y = item.datapoint[1].toFixed(2);
                          var d = new Date(parseInt(x));
                          var contents='<div id="tooltip" class="chart-tooltip"><div class="date">' + $filter('date')(d, 'yyyy-MM-dd') + '</div><div class="label label-success">Total: ' + Number(y) + '</div>';
                          _showTooltip($filter('date')(d, 'yyyy-MM-dd'), item.pageX, item.pageY, contents);
                      }
                  } else {
                      $("#tooltip").remove();
                      previousPoint = null;
                  }
              });
          }
      }

      function _renderPagerContainer($element, $record, data, $scope, $compile) {
          $element.empty();
          var totalRecords = data.totalCount, currentPage = data.currentPage, pagesize = data.pagesize, totalPagers = data.totalPagers, pagerView = '';
          $record.text(totalRecords);
          if (totalRecords) {
              if (1 === currentPage) {
                  pagerView += '<li class="am-disabled pre-page" ng-click="prePage($event)"><a>«</a></li>';
              } else {
                  pagerView += '<li class="pre-page" ng-click="prePage($event)"><a>«</a></li>';
              }

              var startPager = 1;
              if (totalPagers <= 10) {
                  for (var i = startPager; i <= totalPagers; i++) {
                      if (i === currentPage) {
                        pagerView += '<li class="am-active active-pno" data-pno="' + i + '" ng-click="forwardPage($event)"><a>' + i + '</a></li>';
                      }else {
                        pagerView += '<li class="active-pno" data-pno="' + i + '" ng-click="forwardPage($event)"><a>' + i + '</a></li>';
                      }
                  }
              } else {
                  if (currentPage <= totalPagers - 10) {
                      if (currentPage - 6 <= 0) {
                          startPager = 1;
                          for (var i = startPager; i <= 10; i++) {
                              if (i === currentPage) {
                                  pagerView += '<li class="am-active active-pno" data-pno="' + i + '" ng-click="forwardPage($event)"><a>' + i + '</a></li>';
                              }else {
                                  pagerView += '<li class="active-pno" data-pno="' + i + '" ng-click="forwardPage($event)"><a>' + i + '</a></li>';
                              }
                          }
                      } else {
                          for (var i = currentPage - 5; i <= currentPage; i++) {
                              if (i === currentPage) {
                                  pagerView += '<li class="am-active active-pno" data-pno="' + i + '" ng-click="forwardPage($event)"><a>' + i + '</a></li>';
                              }else {
                                  pagerView += '<li class="active-pno" data-pno="' + i + '" ng-click="forwardPage($event)"><a>' + i + '</a></li>';
                              }
                          }

                          if (currentPage === totalPagers || currentPage + 4 > totalPagers) {
                              for (var i = currentPage + 1; i <= totalPagers; i++) {
                                  pagerView += '<li class="active-pno" data-pno="' + i + '" ng-click="forwardPage($event)"><a>' + i + '</a></li>';
                              }
                          } else {
                            for (var i = currentPage + 1; i <= currentPage + 4; i++) {
                                pagerView += '<li class="active-pno" data-pno="' + i + '" ng-click="forwardPage($event)"><a>' + i + '</a></li>';
                            }
                          }
                      }
                  } else {
                      for (var i = totalPagers - 9; i <= totalPagers; i++) {
                          if (i === currentPage) {
                              pagerView += '<li class="am-active active-pno" data-pno="' + i + '" ng-click="forwardPage($event)"><a>' + i + '</a></li>';
                          } else {
                              pagerView += '<li class="active-pno" data-pno="' + i + '" ng-click="forwardPage($event)"><a>' + i + '</a></li>';
                          }
                      }
                  }
              }

            if (totalPagers > 1 && currentPage !== totalPagers) {
                pagerView += '<li class="next-page" ng-click="nextPage($event)"><a>»</a></li>';
            } else {
                pagerView += '<li class="am-disabled next-page" ng-click="nextPage($event)"><a>»</a></li>';
            }

            var template = angular.element(pagerView);
            var pagerContainer = $compile(template)($scope);
            angular.element($element).append(pagerContainer);
          }
      };

      function _showErrorMessage (title, content) {
          $('#error-message-modal').find('.am-modal-bd').html(content);
          $('#error-message-modal').modal({
              width: 335,
              height: 200
          });
      }

      function _showTooltip(title, x, y, contents) {
          var d = new Date(x);
          $(contents).css({
              'position': 'absolute',
              'display': 'none',
              'top': y - 100,
              'width': 75,
              'left': x - 40,
              'border': '0px solid #ccc',
              'padding': '2px 6px',
              'background-color': '#fff',
          }).appendTo("body").fadeIn(200);
      };

      function _renderSelect () {
          var $selects = $('select');
          $selects.each(function() {
              var select = $(this)[0];
              if (typeof(select) !== 'undefined' && select.className.indexOf('quest-type-select') < 0) {
                  if (select.options.length) {
                      $(select).selected();
                  }
              }
          });
      }

      return {
        renderPagerContainer: _renderPagerContainer,
        showErrorMessage: _showErrorMessage,
        showTooltip: _showTooltip,
        getChartOptions: _getChartOptions,
        renderChart: _renderChart,
        renderSelect: _renderSelect,
        showModal: _showModal,
        validateForm: _validateForm,
        uploadFile: _angularUploadFile,
        clearValidForm: _clearValidForm,
        renderNicEditor: _renderNicEditor,
        getNicEditor: _getNicEditor
      }

    }]);

    services.factory('AdminService', ['$rootScope', '$http', function( $rootScope, $http) {

        function _login (data) {
            var loginURL = url.loginURL();
            return $http.post(loginURL, data);
        }

        function Admin() {
            if (Admin.instance === 'object') {
                return Admin.instance;
            }

            function _getCookie(key) {
              var keyStart, keyEnd, keyValue = null;

              if (document.cookie.length > 0) {
                    keyStart = document.cookie.indexOf(key + "=");
                    
                    if (keyStart != -1) { 
                        keyStart = keyStart + key.length + 1; 
                        keyEnd = document.cookie.indexOf(";", keyStart);
                      
                        if (keyEnd == -1) {
                            keyEnd = document.cookie.length;
                        }
                      
                      keyValue = unescape(document.cookie.substring(keyStart, keyEnd));
                    } 
              }

              return keyValue;
          }

          function _setCookie(key, value, expiredays) {
              var exdate = new Date();

              if (!expiredays) {
                  expiredays = 5*365;
              }

              exdate.setDate(exdate.getDate() + expiredays);
              document.cookie = key + "=" + escape(value) + ";expires=" + exdate.toGMTString();
          }

          function _delCookie(key) {
              var exp, cval;
              cval = _getCookie(key);
                
              if (cval != null) {
                  exp = new Date();
                  exp.setTime(exp.getTime() - 1);
                  document.cookie = key + "="+cval+";expires="+exp.toGMTString();
              }
          }

          Admin.prototype.setName = function(name) {
              _setCookie('name', name);
          }

          Admin.prototype.setAccessToken = function(accessToken, rememberMe) {
              if (rememberMe) {
                  _setCookie('accessToken', accessToken);
              } else {
                  _setSessionToken(accessToken);
              }
          }

          function _setSessionToken(accessToken) {
              sessionStorage.setItem('accessToken', accessToken);
          }


          Admin.prototype.getName = function() {
              return _getCookie('name');;
          }

          Admin.prototype.getSessionName = function() {
              return sessionStorage.getItem('name');
          }

          Admin.prototype.getAccessToken = function() {
              return _getCookie('accessToken');
          }

          Admin.prototype.getSessionAccessToken = function() {
              return sessionStorage.getItem('accessToken');
          }

          Admin.prototype.logout = function() {
              $rootScope.accessToken = null;
              $rootScope.login = false;

              _delCookie('accessToken');
              _delCookie('name');
              sessionStorage.removeItem('accessToken');
              sessionStorage.removeItem('name');
          }

          Admin.prototype.init = function() {
              $rootScope.accessToken = this.getAccessToken() || this.getSessionAccessToken();
              $rootScope.login = true;
              $rootScope.name = this.getName() || this.getSessionName();
          }
        
        Admin.instance = this;
    }

    return {
        Admin: new Admin(),
        login: _login
    };

  }]);
});
